#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkLight.h>
#include <vtkAnimationCue.h>
#include <vtkAnimationScene.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkAnimationCue.h>
#include <cmath>
#include <vector>
#include <string>
#include <vtkAutoInit.h>
using namespace std;
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);


// 行星数据结构
struct Planet {
    std::string name;       // 行星名称
    double radius;          // 半径比例
    double orbitRadius;     // 轨道半径
    double orbitSpeed;      // 轨道速度
    double rotationSpeed;   // 自转速度
    double color[3];        // 颜色
    vtkSmartPointer<vtkActor> actor;  // 行星演员
    double currentAngle;    // 当前角度
    double rotationAngle;   // 当前自转角度（新增）
};

// 动画回调类，负责更新行星位置
class AnimationCallback : public vtkCommand
 {
public:
    static AnimationCallback* New() {
        return new AnimationCallback;
    }

    std::vector<Planet>& planets;
    double LastTime = 0.0;
    AnimationCallback() : planets(*(new std::vector<Planet>)) {}
    AnimationCallback(std::vector<Planet>& p) : planets(p) {}

    virtual void Execute(vtkObject* caller, unsigned long eventId, void* callData) {
        if (eventId != vtkCommand::AnimationCueTickEvent) {
            return;
        }
        // 使用 cue 的时间信息
        vtkAnimationCue* cue = vtkAnimationCue::SafeDownCast(caller);
        if (!cue) return;
    
        double deltaTime = cue->GetDeltaTime(); // 获取帧间时间差
        //打印时间
        cout << "Time: " << deltaTime << std::endl;
        // 更新每个行星的位置
        for (size_t i = 0; i < planets.size(); ++i) {
            // 轨道运动
            planets[i].currentAngle += planets[i].orbitSpeed * deltaTime * 1000;
            double x = planets[i].orbitRadius * cos(planets[i].currentAngle);
            double z = planets[i].orbitRadius * sin(planets[i].currentAngle);
            planets[i].actor->SetPosition(x, 0, z);
            if (i == 0){
                cout << "Initial Position: " << x << ", " << z << std::endl;
            }
             // 自转 - 使用绝对角度控制
            planets[i].rotationAngle += planets[i].rotationSpeed * deltaTime * 10;
            planets[i].actor->SetOrientation(0, planets[i].rotationAngle, 0);
        }
    }
};

int main(int argc, char* argv[]) {
    // 初始化渲染器、渲染窗口和交互器
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    // 添加光源
    vtkSmartPointer<vtkLight> light = vtkSmartPointer<vtkLight>::New();
    light->SetPosition(1, 1, 1);
    light->SetFocalPoint(0, 0, 0);
    renderer->AddLight(light);

    // 创建太阳
    vtkSmartPointer<vtkSphereSource> sunSource = vtkSmartPointer<vtkSphereSource>::New();
    sunSource->SetRadius(5.0);
    sunSource->SetThetaResolution(50);
    sunSource->SetPhiResolution(50);

    vtkSmartPointer<vtkPolyDataMapper> sunMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    sunMapper->SetInputConnection(sunSource->GetOutputPort());

    vtkSmartPointer<vtkActor> sunActor = vtkSmartPointer<vtkActor>::New();
    sunActor->SetMapper(sunMapper);
    sunActor->GetProperty()->SetColor(1.0, 1.0, 0.0);  // 黄色
    sunActor->GetProperty()->SetSpecular(0.8);
    sunActor->GetProperty()->SetSpecularPower(30);
    sunActor->SetPosition(0, 0, 0);  // 太阳位于中心
    
    // 添加太阳自转
    sunActor->RotateY(0.01);
    
    renderer->AddActor(sunActor);

    // 定义行星数据
    std::vector<Planet> planets = {
        {"水星", 0.38, 10.0, 4.0, 0.04, {0.5, 0.5, 0.5}},    // 灰色
        {"金星", 0.95, 15.0, 1.6, 0.02, {0.8, 0.6, 0.4}},    // 金黄色
        {"地球", 1.0, 20.0, 1.0, 0.03, {0.2, 0.2, 1.0}},     // 蓝色
        {"火星", 0.53, 25.0, 0.8, 0.035, {1.0, 0.0, 0.0}},   // 红色
        {"木星", 3.0, 35.0, 0.4, 0.05, {0.8, 0.6, 0.2}},     // 棕黄色
        {"土星", 2.5, 50.0, 0.3, 0.045, {0.9, 0.8, 0.6}},    // 淡棕色
        {"天王星", 2.0, 60.0, 0.2, 0.04, {0.6, 0.8, 0.8}},   // 淡蓝色
        {"海王星", 1.9, 70.0, 0.15, 0.038, {0.0, 0.0, 0.8}}, // 深蓝色
        {"冥王星", 0.19, 80.0, 0.1, 0.03, {0.8, 0.8, 0.8}}   // 浅灰色
    };

    // 创建行星
    for (size_t i = 0; i < planets.size(); ++i) {
        vtkSmartPointer<vtkSphereSource> planetSource = vtkSmartPointer<vtkSphereSource>::New();
        planetSource->SetRadius(planets[i].radius);
        planetSource->SetThetaResolution(30);
        planetSource->SetPhiResolution(30);

        vtkSmartPointer<vtkPolyDataMapper> planetMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
        planetMapper->SetInputConnection(planetSource->GetOutputPort());

        planets[i].actor = vtkSmartPointer<vtkActor>::New();
        planets[i].actor->SetMapper(planetMapper);
        planets[i].actor->GetProperty()->SetColor(planets[i].color);
        planets[i].actor->GetProperty()->SetSpecular(0.5);
        planets[i].actor->GetProperty()->SetSpecularPower(20);
        
        // 初始化角度
        planets[i].currentAngle = vtkMath::Random() * 2 * vtkMath::Pi();
        
        // 计算初始位置
        double x = planets[i].orbitRadius * cos(planets[i].currentAngle);
        double z = planets[i].orbitRadius * sin(planets[i].currentAngle);
        
        planets[i].actor->SetPosition(x, 0, z);

        renderer->AddActor(planets[i].actor);
    }

    // 设置背景为黑色（星空）
    renderer->SetBackground(0.0, 0.0, 0.0);

    // 设置相机位置
    vtkSmartPointer<vtkCamera> camera = vtkSmartPointer<vtkCamera>::New();
    camera->SetPosition(0, 100, 0);  // 从Y轴上方俯视
    camera->SetFocalPoint(0, 0, 0);
    camera->SetViewUp(0, 0, 1);
    renderer->SetActiveCamera(camera);
    renderer->ResetCameraClippingRange();

    // 设置动画
    vtkSmartPointer<vtkAnimationScene> animationScene = 
        vtkSmartPointer<vtkAnimationScene>::New();
    animationScene->SetModeToSequence();
    animationScene->SetLoop(1);  // 循环播放
    animationScene->SetStartTime(0);
    animationScene->SetEndTime(100);  // 设置合理的结束时间
    animationScene->SetFrameRate(30);
    vtkSmartPointer<AnimationCallback> callback = 
        vtkSmartPointer<AnimationCallback>::New();
    callback->planets = planets;

    vtkSmartPointer<vtkAnimationCue> cue = vtkSmartPointer<vtkAnimationCue>::New();
    cue->AddObserver(vtkCommand::AnimationCueTickEvent, callback);
    cue->SetStartTime(0);
    cue->SetEndTime(100);

        vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(1000, 800);
    renderWindow->SetWindowName("VTK太阳系模拟");

    vtkSmartPointer<vtkRenderWindowInteractor> interactor = 
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    interactor->SetInteractorStyle(style);
    animationScene->AddCue(cue);
    // 初始化并启动
    renderWindow->Render();
    interactor->Initialize();
    // animationScene->Play();
    interactor->Start();

    return 0;
}
